<script>
import { defineComponent, watch, reactive } from 'vue'
import { createNamespace } from '../utils'
import FanPicker from '../picker/picker.vue'

export default defineComponent({
	name: createNamespace('DatePicker')[0],
	options: { virtualHost: true },
	emits: ['update:show', 'update:modelValue', 'confirm', 'cancel'],
	components: { FanPicker },
	props: {
		modelValue: {
			type: Array,
			default: () => [],
		},
		show: {
			type: Boolean,
			default: false
		},
		title: String,
		minDate: Date,
		maxDate: Date,
		filter: {
			type: [Function, null],
			default: null
		},
		cancelText: {
			type: String,
			default: '取消',
		},
		confirmText: {
			type: String,
			default: '确认',
		},
	},
	setup(props, { emit }) {
		const state = reactive({
			innerShow: props.show,
			value: props.modelValue,
			list: []
		})


		const formatDate = (list) => {
			if (props.filter) state.list = props.filter(list)
			else state.list = list
		}

		const d = new Date()
		let minYear = d.getFullYear() - 10
		let maxYear = d.getFullYear() + 10
		const formatItem = (num, type, i, isSub) => {
			return Array.from({ length: num }, (_, index) => ({
				text: index + 1 < 10 ? `0${index + 1}` : String(index + 1),
				id: index + 1 < 10 ? `0${index + 1}` : String(index + 1),
				type,
				children: isSub ? fillDate(minYear + i, index + 1) : []
			}))
		}
		const init = () => {
			if (props.minDate) minYear = props.minDate.getFullYear()
			if (props.maxDate) maxYear = props.maxDate.getFullYear()
			// 时间相反的情况处理
			if (minYear > maxYear) {
				const min = maxYear
				maxYear = minYear
				minYear = min
			}
			const num = maxYear - minYear
			const list = []
			for (let i = 0; i <= num; i++) {
				list.push({
					text: String(minYear + i),
					id: String(minYear + i),
					type: 'year',
					children: formatItem(12, 'month', i, true)
				})
			}
			formatDate(list)
		}

		const fillDate = (year, month) => {
			const lm = [1, 3, 5, 7, 8, 10, 12]
			const sm = [4, 6, 9, 11]
			if (lm.includes(month)) return formatItem(31, 'day')
			else if (sm.includes(month)) return formatItem(30, 'day')
			else
				if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) return formatItem(29, 'day')
				else return formatItem(28, 'day')
		}

		const onConfirm = (val) => emit('confirm', val)
		const onCancel = () => emit('cancel')

		watch(props.modelValue, (val) => {
			state.value = [...val]
		}, { deep: true })
		watch(() => state.value, (val) => {
			emit('update:modelValue', val)
		}, { deep: true })

		watch(() => props.show, (val) => state.innerShow = val)
		watch(() => state.innerShow, (val) => emit('update:show', val))

		init()

		return { state, onConfirm, onCancel }
	}
})
</script>

<template>
	<FanPicker v-model="state.value" v-model:show="state.innerShow" :data="state.list" value-key="id" :title="title"
		:cancel-text="cancelText" :confirm-text="confirmText" @confirm="onConfirm" @cancel="onCancel">
		<template v-if="$slots.default" #header>
			<slot />
		</template>
	</FanPicker>
</template>
